﻿<!DOCTYPE HTML>
<html lang="zh">
<head>
<title>Loop Read - 语法 &amp; 使用 | AutoHotkey v2</title>
<meta name="description" content="The Loop Read statement retrieves the lines in a text file, one at a time." />
<meta name="ahk:equiv-v1" content="commands/LoopReadFile.htm" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<link href="../static/theme.css" rel="stylesheet" type="text/css" />
<script src="../static/content.js" type="text/javascript"></script>
<script type="text/javascript">$(function(){0<=window.navigator.userAgent.toLowerCase().indexOf("ucbrowser")&&CaoNiMaDeUc()})</script>
</head>
<body>

<h1>Loop Read</h1>

<p>Retrieves the lines in a text file, one at a time.</p>

<pre class="Syntax"><span class="func">Loop Read</span> InputFile <span class="optional">, OutputFile</span></pre>
<h2 id="Parameters">参数</h2>
<dl>

  <dt>InputFile</dt>
  <dd>
    <p>类型: <a href="../Concepts.htm#strings">字符串</a></p>
    <p>The name of the text file whose contents will be read by the loop, which is assumed to be in <a href="../Variables.htm#WorkingDir">A_WorkingDir</a> if an absolute path isn't specified. The file's lines may end in carriage return and linefeed (`r`n), just linefeed (`n), or just carriage return (`r).</p>
  </dd>

  <dt>OutputFile</dt>
  <dd>
      <p>类型: <a href="../Concepts.htm#strings">字符串</a></p>
      <p>The name of the file to be kept open for the duration of the loop, which is assumed to be in <a href="../Variables.htm#WorkingDir">A_WorkingDir</a> if an absolute path isn't specified.</p>
      <p>Within the loop's body, use the <a href="FileAppend.htm">FileAppend</a> function without the <em>Filename</em> parameter (i.e. omit it) to append to this special file. Appending to a file in this manner performs better than using <a href="FileAppend.htm">FileAppend</a> in its 2-parameter mode because the file does not need to be closed and re-opened for each operation. Remember to include a linefeed (`n) or carriage return and linefeed (`r`n) after the text, if desired.</p>
      <p>The file is not opened if nothing is ever written to it. This happens if the Loop performs zero iterations or if it never calls <a href="FileAppend.htm">FileAppend</a>.</p>
      <p><strong>Options</strong>: The end of line (EOL) translation mode and output file encoding depend on which options are passed in the opening call to <a href="FileAppend.htm">FileAppend</a> (i.e. the first call which omits <em>Filename</em>). Subsequent calls ignore the <em>Options</em> parameter. EOL translation is not performed by default; that is, linefeed (`n) characters are written as-is unless the <code>"`n"</code> option is present.</p>
      <p><strong>Standard Output (stdout)</strong>: Specifying an asterisk (*) for <em>OutputFile</em> sends any text written by <a href="FileAppend.htm">FileAppend</a> to standard output (stdout). Although such output can be redirected to a file, piped to another EXE, or captured by <a href="_ErrorStdOut.htm">fancy text editors</a>, it will not appear at the command prompt it was launched from. See <a href="FileAppend.htm">FileAppend</a> for more details.</p>
  </dd>

</dl>

<h2 id="Remarks">备注</h2>
<p>A file-reading loop is useful when you want to operate on each line contained in a text file, one at a time. The file is kept open for the entire operation to avoid having to re-scan each time to find the next line.</p>
<p id="LoopReadLine">The built-in variable <strong>A_LoopReadLine</strong> exists within any file-reading loop. It contains the contents of the current line excluding the carriage return and linefeed (`r`n) that marks the end of the line. If an inner file-reading loop is enclosed by an outer file-reading loop, the innermost loop's file-line will take precedence.</p>
<p>Lines up to 65,534 characters long can be read. If the length of a line exceeds this, its remaining characters will be read during the next loop iteration.</p>
<p><a href="StrSplit.htm">StrSplit</a> or a <a href="LoopParse.htm">parsing loop</a> is often used inside a file-reading loop to parse the contents of each line retrieved from <em>InputFile</em>. 例如, if <em>InputFile</em>'s lines are each a series of tab-delimited fields, those fields can individually retrieved as in this example:</p>
<pre>Loop read, "C:\Database Export.txt"
{
    Loop parse, A_LoopReadLine, A_Tab
    {
        MsgBox "Field number " A_Index " is " A_LoopField "."
    }
}</pre>
<p>To load an entire file into a variable, use <a href="FileRead.htm">FileRead</a> because it performs much better than a loop (especially for large files).</p>
<p>To have multiple files open simultaneously, use <a href="FileOpen.htm">FileOpen</a>.</p>
<p>请参阅 <a href="Loop.htm">Loop</a> 了解关于<a href="Block.htm">区块</a>, <a href="Break.htm">Break</a>, <a href="Continue.htm">Continue</a> 和 A_Index 变量(其存在于各种类型的循环中) 的相关信息.</p>
<p>To control how the file is decoded when no byte order mark is present, use <a href="FileEncoding.htm">FileEncoding</a>.</p>

<h2 id="Related">相关</h2>
<p><a href="FileEncoding.htm">FileEncoding</a>, <a href="FileOpen.htm">FileOpen</a>/<a href="../objects/File.htm">File Object</a>, <a href="FileRead.htm">FileRead</a>, <a href="FileAppend.htm">FileAppend</a>, <a href="Sort.htm">Sort</a>, <a href="Loop.htm">Loop</a>, <a href="Break.htm">Break</a>, <a href="Continue.htm">Continue</a>, <a href="Block.htm">Blocks</a>, <a href="FileSetAttrib.htm">FileSetAttrib</a>, <a href="FileSetTime.htm">FileSetTime</a></p>

<h2 id="Examples">示例</h2>
<div class="ex" id="ExFileAppend">
<p><a href="#ExFileAppend">#1</a>: Only those lines of the 1st file that contain the word FAMILY will be written to the 2nd file. Uncomment the first line to overwrite rather than append to any existing file.</p>
<pre><em>;FileDelete "C:\Docs\Family Addresses.txt"</em>

Loop read, "C:\Docs\Address List.txt", "C:\Docs\Family Addresses.txt"
{
    if InStr(A_LoopReadLine, "family")
        FileAppend(A_LoopReadLine "`n")
}</pre>
</div>

<div class="ex" id="ExLastLine">
<p><a href="#ExLastLine">#2</a>: Retrieve the last line from a text file.</p>
<pre>Loop read, "C:\Log File.txt"
    last_line := A_LoopReadLine  <em>; When loop finishes, this will hold the last line.</em></pre>
</div>

<div class="ex" id="ExURL">
<p><a href="#ExURL">#3</a>: A working script that attempts to extract all FTP and HTTP URLs from a text or HTML file:</p>
<pre>SourceFile := FileSelect(3,, "Pick a text or HTML file to analyze.")
if SourceFile = ""
    return  <em>; This will exit in this case.</em>

SplitPath SourceFile,, SourceFilePath,, SourceFileNoExt
DestFile := SourceFilePath "\" SourceFileNoExt " Extracted Links.txt"

if FileExist(DestFile)
{
    Result := MsgBox("Overwrite the existing links file? Press No to append to it.`n`nFILE: " DestFile,, 4)
    if Result = "Yes"
        FileDelete DestFile
}

LinkCount := 0
Loop read, SourceFile, DestFile
{
    URLSearchString := A_LoopReadLine
    Gosub URLSearch
}
MsgBox LinkCount ' links were found and written to "' DestFile '".'
return


URLSearch:
<em>; It's done this particular way because some URLs have other URLs embedded inside them:</em>
URLStart1 := InStr(URLSearchString, "http://")
URLStart2 := InStr(URLSearchString, "ftp://")
URLStart3 := InStr(URLSearchString, "www.")

<em>; Find the left-most starting position:</em>
URLStart := URLStart1  <em>; Set starting default.</em>
Loop
{
    <em>; It helps performance (at least in a script with many variables) to resolve</em>
    <em>; &quot;URLStart%A_Index%&quot; only once:</em>
    ArrayElement := URLStart%A_Index%
    if ArrayElement = ""  <em>; End of the <a href="../misc/Arrays.htm#pseudo">pseudo-array</a> has been reached.</em>
        break
    if !ArrayElement  <em>; This element is disqualified.</em>
        continue
    if !URLStart
        URLStart := ArrayElement
    else <em>; URLStart has a valid position in it, so compare it with ArrayElement.</em>
    {
        if ArrayElement
            if ArrayElement &lt; URLStart
                URLStart := ArrayElement
    }
}

if !URLStart  <em>; No URLs exist in URLSearchString.</em>
    return

<em>; Otherwise, extract this URL:</em>
URL := SubStr(URLSearchString, URLStart)  <em>; Omit the beginning/irrelevant part.</em>
Loop parse, URL, " `t&lt;&gt;"  <em>; Find the first space, tab, or angle bracket (if any).</em>
{
    URL := A_LoopField
    break  <em>; i.e. perform only one loop iteration to fetch the first &quot;field&quot;.</em>
}
<em>; If the above loop had zero iterations because there were no ending characters found,
; leave the contents of the URL var untouched.</em>

<em>; If the URL ends in a double quote, remove it.  For now, StrReplace is used, but
; note that it seems that double quotes can legitimately exist inside URLs, so this
; might damage them:</em>
URLCleansed := StrReplace(URL, '"')
FileAppend URLCleansed "`n"
LinkCount += 1

<em>; See if there are any other URLs in this line:</em>
CharactersToOmit := StrLen(URL)
CharactersToOmit += URLStart
URLSearchString := SubStr(URLSearchString, CharactersToOmit)
Gosub URLSearch  <em>; Recursive call to self.</em>
return</pre>
</div>

</body>
</html>